サロゲートキー v.s. 複合主キーでは、前者を選ぶ
複合主キーを選択できるような状況では常に、以下の2つの選択肢を取ることができる どこの対立の話をしているのか整理
サロゲートキーを選択する場合、以下の2つをやっておく
サロゲートキーの追加
これで煩雑さも解消しつつ、UNIQUEであることを担保できる
こんな例
table:table
id Product id Category id
このidがサロゲートキー
Product IdとCateogry Idの組はユニークである
複合主キーの候補として挙げていたので当たり前mrsekut.icon
サロゲートキーの良さと、複合主キーの問題
複合主キーの組に修正が入った場合に、修正コストが高い
a,bという複合主キーから、a,b,cになった時に、問題になる
このtableを、外部キー制約として他のtableから参照されている時
制約の張り方を修正しないといけないはず
複合主キーに1つ加えた場合、既存のSQLでこのtableをjoinしている箇所は全て条件落ちの状態になる これは、気づきづらい、というのが問題
コンパイルエラーにも、実行時エラーにもならない
複合主キーを用いたtableと結合する際は、全てのキーに対して結合条件を指定しないといけないが、うっかり漏れる (条件落ち) サロゲートキーを用いていれば、このような修正コストはかからない
(immutable data構造的には、cを追加するのではなく、新しいtableを作るべき、という気もするけどmrsekut.icon)
そもそも複合主キーは2つの責務を持っていることになる
業務的な一つのレコードを特定する
システム的な一つのレコードを特定する
サロゲートキーを導入することで、後者の責務を破棄できるためシンプルになる
複合主キーを選択しても良いときはいつか?
そのtableが未来永劫修正されない場合
そのtableが他のどのtableからも参照されない場合
そのtableが他のどのtableからもJOINされない場合
ただ、この修正されないかどうかとか、外部から参照されないかどうかは作成時にはわからないmrsekut.icon
もし修正された場合のコストと、ただサロゲートキーを追加するだけのコストを比較すると、やはり後者に軍配が上がらざるを得ない気がするmrsekut.icon
参考
参考にはなるが、「サロゲートキーの方が良い」を前提に比較している感はある
複合主キーのメリットは一応書いてますよぐらい
単純にサロゲートキーのデメリットと、複合主キーのメリデメを比較すると、後者を選択する理由がかなり薄い
折衷する理由すら薄い
このtableではサロゲートキー、このtableでは複合主キーを採用する、ということをする意義自体が薄いmrsekut.icon
全部前者統一で良い
サロゲートキーデメリット
本番環境とテスト環境などで、DBのインスタンスが異なると、同じ意味を持つ行が別の主キーを持ちうる
データ移行の時に考えなければならないことが増える
サロゲートキーをつけない場合よりもインデックスが増えるため、更新時の性能が落ちる場合がある
DB関係なく、アプリ上で、その概念を特定するために、複数の値を持ち回る必要があるということ
例えば、一つの投稿を特定するために3つの値を持ち回る必要があることを考えるとかなりだるいことがわかる
これはたしかにそうだと思うが、これが必要なケースは複合主キーを選択肢に入れない気がするなmrsekut.icon
でも、「どう使われるか」はあまり考えるべきでもない気がするから、こういう問題が生じうる時点で複合主キーは選択すべきでないのかもしれない
複合主キーを使う派
以下のような例
社員テーブルと、趣味テーブルを結合した社員趣味テーブルを考える
社員趣味テーブルI
table:社員趣味テーブル I
社員id a(社員tableのPK) 趣味id g(趣味tableのPK) 趣味の好みの程度 d
サロゲートキーを用いずに、aとgの複合主キーにする
社員趣味テーブルII
table:社員趣味テーブル II
サロゲートキーh(PK) 社員id a(社員tableのPK) 趣味id g(趣味tableのPK) 趣味の好みの程度 d
サロゲートキーを導入し、
aとgにはユニーク制約を設ける
筆者はIの方が良いと主張
その心は、
IIを採用すると、
社員趣味テーブルが、他のテーブルから参照されている時に、
社員tableや趣味tableでaやdの値が変わった時に、hが意味の異なるデータを指すようになるから
というもの
これは変な気がするmrsekut.icon
「aやdに変更がありうる」という状況がおかしいmrsekut.icon
その時点で、aやdはナチュラルキーっぽい
なぜ記事の最初にナチュラルキーとサロゲートキーを対比しているのに、こんな論理になるのかわからん
こういうことが起こらないようにするために「ナチュラルキーを主キーにしない」んじゃないのか
UNIQUE制約付けるなら、サロゲートキー(id)不要じゃん、という意見
意見が薄いmrsekut.icon